package com.execjar.tcptools;

public class HexStrConver {
	/**
	 * 字符串转换成十六进制字符串
	 *
	 * @param String
	 *            str 待转换的ASCII字符串
	 * @return String 每个Byte之间空格分隔，如: [61 6C 6B]
	 */
	public static String str2HexStr(String str) {

		char[] chars = "0123456789ABCDEF".toCharArray();
		StringBuilder sb = new StringBuilder("");
		byte[] bs = str.getBytes();
		int bit;

		for (int i = 0; i < bs.length; i++) {
			bit = (bs[i] & 0x0f0) >> 4;
			sb.append(chars[bit]);
			bit = bs[i] & 0x0f;
			sb.append(chars[bit]);
			sb.append(' ');
		}
		return sb.toString().trim();
	}

	/**
	 * 十六进制转换字符串
	 *

	 *            str Byte字符串(Byte之间无分隔符 如:[616C6B])
	 * @return String 对应的字符串
	 */
	public static String hexStr2Str(String hexStr) {
		String str = "0123456789ABCDEF";
		char[] hexs = hexStr.toCharArray();
		byte[] bytes = new byte[hexStr.length() / 2];
		int n;

		for (int i = 0; i < bytes.length; i++) {
			n = str.indexOf(hexs[2 * i]) * 16;
			n += str.indexOf(hexs[2 * i + 1]);
			bytes[i] = (byte) (n & 0xff);
		}
		return new String(bytes);
	}

	/**
	 * bytes转换成十六进制字符串
	 *
	 * @param byte[] b byte数组
	 * @return String 每个Byte值之间空格分隔
	 */
	public static String byte2HexStr(byte[] b) {
		String stmp = "";
		StringBuilder sb = new StringBuilder("");
		for (int n = 0; n < b.length; n++) {
			stmp = Integer.toHexString(b[n] & 0xFF);
			sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
			sb.append(" ");
		}
		return sb.toString().toUpperCase().trim();
	}

	/**
	 * bytes字符串转换为Byte值
	 *
	 * @param String
	 *            src Byte字符串，每个Byte之间没有分隔符
	 * @return byte[]
	 */
	public static byte[] hexStr2Bytes(String src) {
		int m = 0, n = 0;
		int l = src.length() / 2;
//		System.out.println(l);
		byte[] ret = new byte[l];
		for (int i = 0; i < l; i++) {
			m = i * 2 + 1;
			n = m + 1;
			ret[i] = Byte.decode("0x" + src.substring(i * 2, m)
					+ src.substring(m, n));
		}

		return ret;
	}

	/**
	 * String的字符串转换成unicode的String
	 *
	 * @param String
	 *            strText 全角字符串
	 * @return String 每个unicode之间无分隔符
	 * @throws Exception
	 */
	public static String strToUnicode(String strText) throws Exception {
		char c;
		StringBuilder str = new StringBuilder();
		int intAsc;
		String strHex;
		for (int i = 0; i < strText.length(); i++) {
			c = strText.charAt(i);
			intAsc = (int) c;
			strHex = Integer.toHexString(intAsc);
			if (intAsc > 128)
				str.append("\\u" + strHex);
			else
				// 低位在前面补00
				str.append("\\u00" + strHex);
		}
		return str.toString();
	}

	/**
	 * unicode的String转换成String的字符串
	 *
	 * @param String
	 *            hex 16进制值字符串 （一个unicode为2byte）
	 * @return String 全角字符串
	 */
	public static String unicodeToString(String hex) {
		int t = hex.length() / 6;
		StringBuilder str = new StringBuilder();
		for (int i = 0; i < t; i++) {
			String s = hex.substring(i * 6, (i + 1) * 6);
			// 高位需要补上00再转
			String s1 = s.substring(2, 4) + "00";
			// 低位直接转
			String s2 = s.substring(4);
			// 将16进制的string转为int
			int n = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16);
			// 将int转换为字符
			char[] chars = Character.toChars(n);
			str.append(new String(chars));
		}
		return str.toString();
	}

	/**
	 * 16进制的字符串表示转成字节数组
	 *
	 * @param hexString 16进制格式的字符串
	 * @return 转换后的字节数组
	 **/
	public static byte[] toByteArray(String hexString) {

		final byte[] byteArray = new byte[hexString.length() / 2];

	    if (hexString!=null&&!("").equals(hexString)){
	    	hexString = hexString.toLowerCase();
	 	    int k = 0;
	 	    for (int i = 0; i < byteArray.length; i++) {//因为是16进制，最多只会占用4位，转换成字节需要两个16进制的字符，高位在先
	 	        byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
	 	        byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
	 	        byteArray[i] = (byte) (high << 4 | low);
	 	        k += 2;
	 	    }
	    }

	    return byteArray;
	}


	 public static byte[] hexStringToBytes(String hexString) {
	        if (hexString == null || hexString.equals("")) {
	            return null;
	        }
	        // toUpperCase将字符串中的所有字符转换为大写
	        hexString = hexString.toUpperCase();
	        int length = hexString.length() / 2;
	        // toCharArray将此字符串转换为一个新的字符数组。
	        char[] hexChars = hexString.toCharArray();
	        byte[] d = new byte[length];
	        for (int i = 0; i < length; i++) {
	            int pos = i * 2;
	            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
	        }
	        return d;
	    }
	    //charToByte返回在指定字符的第一个发生的字符串中的索引，即返回匹配字符
	    private static byte charToByte(char c) {
	        return (byte) "0123456789ABCDEF".indexOf(c);
	    }

	    /**
		 * 16进制的字符串表示转成ASCII字节数组
		 *
		 * @param hexString 16进制格式的字符串
		 * @return 转换后的字节数组
		 **/
		public static byte[] toByteArray2(String hexString) {
		    if (hexString!=null&&!("").equals(hexString)){
		    	hexString=hexString.replace(" ", "");
		    	byte[] byteArray = new byte[hexString.length() / 2];
		    	hexString = hexString.toLowerCase();
		 	    int k = 0;
		 	    for (int i = 0; i < byteArray.length; i++) {//因为是16进制，最多只会占用4位，转换成字节需要两个16进制的字符，高位在先
		 	        byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
		 	        byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
		 	        byteArray[i] = (byte) (high << 4 | low);
		 	        k += 2;
		 	    }
		 	   return byteArray;
		    }else{
		    	return null;
		    }
		}


	/**
	 * 二进制字符串转十六进制字符串
	 * **/
	public static String conver2HexStr(String str) {
		String sum = "";
		int t = str.length() % 4;
		if (t != 0) {
			for (int i = str.length(); i - 4 >= 0; i = i - 4) {
				String s = str.substring(i - 4, i);
				int tem = Integer.parseInt(String.valueOf(s), 2);
				sum = Integer.toHexString(tem).toUpperCase() + sum;
			}
			String st = str.substring(0, t);
			int tem = Integer.parseInt(String.valueOf(st), 2);
			sum = Integer.toHexString(tem).toUpperCase() + sum;
		} else {
			for (int i = str.length(); i - 4 >= -1; i = i - 4) {
				String s = str.substring(i - 4, i);
				int tem = Integer.parseInt(String.valueOf(s), 2);
				sum = Integer.toHexString(tem).toUpperCase() + sum;
			}
		}
		return sum;
	}

	/**
	 * byte数组转换为二进制字符
	 **/
	public static String byteArrToBinStr(byte[] b) {
		StringBuffer result = new StringBuffer();
		for (int i = 0; i < b.length; i++) {
			result.append(Long.toString(b[i] & 0xff, 2));
		}
		return result.toString();
	}
}
